#include "server.h"

int ExitPipe[2];

//传入参数：信号值
//通知父进程退出
void ExitFunc(int SigNum){
    printf("signal %d is coming",SigNum);

    char ch=1;
    write(ExitPipe[1],&ch,1);
}

//传入参数ip,port,threadnum
int main(int argc,char *argv[]){
    
    ARGS_CHECK(argc,4);

    signal(SIGUSR1,ExitFunc);
    
    int threadNum=atoi(argv[3]);
    char *ip=argv[1];
    int port=atoi(argv[2]);

    pipe(ExitPipe);

    pid_t pid=fork();

    if(pid>0){
        close(ExitPipe[0]);
        wait(NULL);
        exit(0);
    }

    //子进程操作
    close(ExitPipe[1]);
    thread_pool_t threadPool;
    threadpoolInit(&threadPool,threadNum);
    threadpoolStart(&threadPool);

    int listenfd=tcpServerInit(ip,port);

    int epfd=epollCreate();
    epollAddReadEvent(epfd,listenfd);
    epollAddReadEvent(epfd,ExitPipe[0]);

    struct epoll_event *pEvtList=(struct epoll_event *)calloc(MAXCONNS,sizeof(struct epoll_event));

    int nReady;
    while(1){
        do{
            nReady=epoll_wait(epfd,pEvtList,MAXCONNS,5000);
        }while(nReady==-1&&errno==EINTR);

        if(nReady==0){
            printf(">>epoll timeout.\n");
            continue;
        }else if(nReady==-1){
            perror("epoll_wait");
            return EXIT_FAILURE;
        }else{
            for(int i=0;i<nReady;i++){
                int fd=pEvtList[i].data.fd;
                if(fd==listenfd){
                    int peerfd=accept(listenfd,NULL,NULL);
                    if(peerfd<0){
                        perror("accept");
                    }
                    printf("accept a new connect.peerfd:%d\n",peerfd);

                    taskEnqueue(&threadPool.queue,peerfd);
                }else if(fd==ExitPipe[0]){
                    char exitFlag;
                    read(ExitPipe[0],&exitFlag,1);
                    printf("parent process ready to exit.\n");

                    //收到退出通知，子进程逐步退出
                    queueWakeup(&threadPool.queue);
                    for(int j=0;j<threadNum;j++){
                        pthread_join(threadPool.threads[j],NULL);
                    }

                    printf("parent process pool exit.\n");
                    threadpoolDestroy(&threadPool);
                    exit(0);
                }else{
                   
                    threadFunc(&threadPool);

                }
            }
        }
    }
    free(pEvtList);
    close(listenfd);
    close(epfd);
    return 0;

}
